
use std::cell::{RefCell, RefMut, Ref};
use crate::kvdb::traits::{Tables, DBError, DB};

use crate::kvdb::mock_tables::MockTables;

/*
 *   memory rbtree_map impl for DB-Tables-Table
 */
pub struct MockDB {
    name: String,
    tables: Box<RefCell<dyn Tables>>,
    opened: bool,
}

impl MockDB {
    pub fn new(name: &str)-> MockDB {
        MockDB {
            name: name.to_owned(),
            tables: Box::new(RefCell::new(MockTables::new())),
            opened: false,
        }
    }
}

impl DB for MockDB {
    fn open(&mut self) -> Result<bool, DBError>{
        if self.opened {
            self.opened = true;
            return Ok(true);
        }
        Ok(false)
    }
    fn close(&mut self) -> Result<bool, DBError>{
        if !self.opened {
            self.opened = false;
            return Ok(true);
        }
        Ok(false)
    }

    fn name(&self) -> &str {
        &self.name
    }
    fn tables(&self) -> Ref<dyn Tables> {
        self.tables.borrow()
    }
    fn tables_mut(&mut self) ->RefMut<dyn Tables>{
        self.tables.borrow_mut()
    }
}

#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn test_mockdb(){
        let mut db = MockDB::new("name");
        assert!(db.open().is_ok());

        assert_eq!(0, (*db.tables()).len());
        assert_eq!(0, (*db.tables_mut()).len());

        assert!(db.tables_mut().create("hello").is_ok());

        assert!(db.close().is_ok());
    }
}

